module dungeon.dice;

import std.string;

import nade.random;
import nade.ast;
import nade.loader;


enum Die {
	CONSTANT,
	D4,
	D6,
	D8,
	D10,
	D12,
	D20,
	D100,
}


class DiceRoll {
	protected {
		int[Die.max + 1]	_values;
	}

	this()
	{
	}
	this(DiceRoll clone)
	{
		_values[0..$] = clone._values[0..$];
	}

	int roll()
	{
		return _values[Die.CONSTANT]
			+ _values[Die.D4]*random(1, 5)
			+ _values[Die.D6]*random(1, 7)
			+ _values[Die.D8]*random(1, 9)
			+ _values[Die.D10]*random(1, 11)
			+ _values[Die.D12]*random(1, 13)
			+ _values[Die.D20]*random(1, 21)
			+ _values[Die.D100]*random(0, 100)
		;
	}

	static void install()
	{
		Loader!(DiceRoll).add(["constant", "const"],
			(ref DiceRoll dice, AST ast, Object[string] state) { dice._values[Die.CONSTANT] = ast[0].as!int; }
		);

		Loader!(DiceRoll).add("d4",
			(ref DiceRoll dice, AST ast, Object[string] state) { dice._values[Die.D4] = ast[0].as!int; }
		);

		Loader!(DiceRoll).add("d6",
			(ref DiceRoll dice, AST ast, Object[string] state) { dice._values[Die.D6] = ast[0].as!int; }
		);

		Loader!(DiceRoll).add("d8",
			(ref DiceRoll dice, AST ast, Object[string] state) { dice._values[Die.D8] = ast[0].as!int; }
		);

		Loader!(DiceRoll).add("d10",
			(ref DiceRoll dice, AST ast, Object[string] state) { dice._values[Die.D10] = ast[0].as!int; }
		);

		Loader!(DiceRoll).add("d12",
			(ref DiceRoll dice, AST ast, Object[string] state) { dice._values[Die.D12] = ast[0].as!int; }
		);

		Loader!(DiceRoll).add("d20",
			(ref DiceRoll dice, AST ast, Object[string] state) { dice._values[Die.D20] = ast[0].as!int; }
		);

		Loader!(DiceRoll).add("d100",
			(ref DiceRoll dice, AST ast, Object[string] state) { dice._values[Die.D100] = ast[0].as!int; }
		);
	}
}
